重点:放在 HashMap 集合 key 部分的元素,以及放在 HashSet 集合的元素,需要同时重写 hashCode 和 equals 方法
- 向 Map 集合中存,以及从 Map 集合中取,都是先调用 key 的 hashCode 方法,然后再调用 equals 方法!equals 方法有可能调用,也有可能不调用
- 拿
put(k, v)
举例,什么时候 equals 不会调用?- k. hashCode() 方法返回哈希值
- 哈希值通过哈希算法转换成数组下标
- 数组下标位置上如果为 null,equals 不需要执行
- 拿
get(k)
举例,什么时候 equals 不会调用?- k. hashCode() 方法返回哈希值
- 哈希值通过哈希算法转换成数组下标
- 数组下标位置上如果为 null,equals 不需要执行
注意:如果一个类的 equals 方法重写了,那么 hashCode() 方法必须重写,并且 equals 方法返回如果是 true,hashCode() 方法返回值必须一样
- equals 方法返回 true,表示两个对象相同,在同一个单向链表上比较,那么对于同一个单向链表上的节点来说,他们的哈希值都是相同的,所以 hashCode() 方法的返回值也应该相同
hashCode() 方法和 equals() 方法不用研究了,直接使用 IDEA 工具生成,但是这两个方法需要同时生成
右键 --> Source --> Generate hashCode() and equals()
对于哈希表数据结构来说:
- 如果 o1 和 o2 的 hash 值相同,一定是放到同一个单向链表上
- 当然如果 o1 和 o2 的 hash 值不同,但由于哈希算法执行结束之后转换的数组下标可能相同,此时会发生“哈希碰撞”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87import java.util.HashSet;
import java.util.Set;
public class HashMapTest02 {
public static void main(String[] args) {
Student s1 = new Student("zhangsan");
Student s2 = new Student("zhangsan");
// 重写 equals 方法之前是 false
// System.out.println(s1.equals(s2)); // false
// 重写 equals 方法之前是 true
System.out.println(s1.equals(s2)); // true
System.out.println("s1的hashCode=" + s1.hashCode()); // 2018699554 // 重写后,hashCode变为 -1432604525
System.out.println("s2的hashCode=" + s2.hashCode()); // 1311053135 // 重写后,hashCode变为 -1432604525
// s1.equals(s2) 结果已经是 true 了,表示 s1 和 s2 是一样的,那么往 HashSet 集合中放的话,
// 按说只能放进去 1 个(HashSet 集合特点:无序不可重复)
Set<Student> students = new HashSet<>();
students.add(s1);
students.add(s2);
System.out.println(students.size()); // 结果是2,显然不符合 HashSet 集合存储特点
}
}
// Student 类
package test0526;
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// hashCode
// equals(如果学生名字一样,表示同一个学生)
// public boolean equals(Object obj) {
// if (obj == null || !(obj instanceof Student))
// return false;
// if (obj == this)
// return true;
// Student s = (Student) obj;
// return this.name.equals(s.name);
// }
//---- 以下是 IDEA 自动生成
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}